package com.xb.controller;

import com.alibaba.druid.sql.PagerUtils;
import com.xb.common.Constant;
import com.xb.dao.UserDao;
import com.xb.entity.PageResult;
import com.xb.entity.Result;
import com.xb.entity.User;
import com.xb.service.UserService;
import com.xb.util.EncryptUtil;
import com.xb.websocket.XBWebSocket;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.web.servlet.server.Session;
import org.springframework.data.domain.Page;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.ValueOperations;
import org.springframework.stereotype.Controller;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpSession;
import java.io.File;
import java.io.IOException;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.UUID;
import java.util.concurrent.TimeUnit;

@RestController
@RequestMapping("user")
public class UserController {

    @Autowired
    private UserService service;

    @Autowired
    private HttpSession session;

    @Autowired
    private RedisTemplate redisTemplate;

//    @RequestMapping()
//    public Result (){
//          return new Result();
//    }

    // 注册用户发送邮件验证码
//    @PostMapping("/sendEmail")
//    public Result sendEmail(String email) {
//        meetingService.sendEmail();
//        return new Result(true, "发送成功");
//    }


    /**
     * 注册 校验邮箱
     *
     * @param email 邮箱地址
     * @return 响应结果集
     */
    @GetMapping("/checkEmail")
    public Result checkEmail(String email) {
        if (!service.checkEmail(email)) return new Result(true, "该邮箱未被注册");
        return new Result(false, "该邮箱已被注册");
    }

    /**
     * 注册 校验用户名
     *
     * @param username 用户名
     * @return 响应结果集
     */
    @GetMapping("/checkUsername")
    public Result checkUsername(String username) {
        if (!service.checkUsername(username)) return new Result(true, "用户名可用");
        return new Result(false, "该用户名已被注册");
    }

    /**
     * 注册 注册用户
     *
     * @param user 用户信息
     * @return 响应结果集
     */
    @PostMapping("/register")
    public Result register(@RequestBody User user) {
        // 默认头像
        user.setPic("https://www.baidu.com/favicon.ico");
        service.save(user);
        return new Result(true, "注册成功");
    }

    /**
     * 重置密码 发送邮件验证码
     *
     * @param email 邮箱地址
     * @return 响应结果集
     */
    @RequestMapping("/sendEmail")
    public Result sendEmail(String email) {
        // 初始化校验结果信息
        String msg;
        // 根据邮箱校验用户是否存在
        if (service.checkEmail(email)) {
            // 获取 jedis 操作对象 ops
            ValueOperations ops = redisTemplate.opsForValue();
            // redis获取验证码
            String emailCode = (String) ops.get("EmailCode:username:" + email);
            // 验证码已过期或未发送邮件
            if (null == emailCode) {
                // 发送验证码，根据邮箱地址，将验证码保存到redis，设置有效期
                ops.set("EmailCode:username:" + email, service.sendEmail(email), Constant.EMAIL_CODE_TIME, TimeUnit.SECONDS);
                return new Result(true, "邮件发送成功,验证码五分钟内有效");
            } else msg = "操作过于频繁";
        } else msg = "邮箱地址不存在，请重新输入";
        return new Result(false, msg);
    }

    /**
     * 用户重置密码
     *
     * @param email    邮箱地址
     * @param code     验证码
     * @param password 新密码
     * @return 响应结果集
     */
    @RequestMapping("/reset")
    public Result reset(String email, String code, String password) {
        // 初始化校验结果信息
        String msg;
        // 校验非空
        if (!StringUtils.isEmpty(email) && !StringUtils.isEmpty(code) && !StringUtils.isEmpty(password)) {
            // 校验邮箱地址是否存在
            if (service.checkEmail(email)) {
                // redis中获取验证码
                String redisCode = (String) redisTemplate.opsForValue().get("EmailCode:username:" + email);
                // 验证码存在
                if (null != redisCode) {
                    // 根据邮箱地址获取用户信息
                    User user = service.findByEmail(email);
                    // 加密重置后密码
//                    user.setPassword(EncryptUtil.MD5_HEX(EncryptUtil.MD5_HEX(password) + user.getUsername()));
                    user.setPassword(password);
                    // 更新用户信息
                    service.updatePassword(user);
                    return new Result(true, "密码重置成功");
                } else msg = "未校验邮箱或验证码已失效，请重新发送";
            } else msg = "邮箱地址有误，请重新输入";
        } else msg = "输入信息有误，请重新输入";
        return new Result(false, msg);
    }

    /**
     * 用户登录
     *
     * @param username 用户名
     * @param password 密码
     * @param code     验证码
     * @param remember 免密登录
     * @return 响应结果集
     */
    @RequestMapping("/login")
    public Result login(String username, String password, String code, Boolean remember) {
        // 初始化登录信息
        String msg = "登录失败，请重新登录";
        // session中的验证码
        Object sessionInCode = session.getAttribute("safeCode");
        // 验证码正确 （旧）
//        if (code.equals(session.getAttribute("checkCode"))) {
//        if (code.equals(session.getAttribute("checkCode"))) {

        if (!code.equals(sessionInCode)) {
            return new Result(false, "验证码错误");
        }

        // 校验用户名
        User loginUser = service.findByUsername(username);
        // 用户名存在
        if (null != loginUser) {
            // 密码正确
            if (password.equals(loginUser.getPassword())) {
                // 免密登录
                if (remember) {
                    // redis保存登录状态
//                        redisTemplate.opsForValue().set("User:LoginUser:userId", loginUser.getId(),Constant.REDIS_REMENBER_DAYS, TimeUnit.DAYS);
                } else {
//                        redisTemplate.opsForValue().set("User:LoginUser:userId", loginUser.getId(),Constant.KEEP_LOGIN_MINUTE, TimeUnit.MINUTES);
                }
                session.setAttribute("loginUser", loginUser.getUsername());
                Map<String, String> map = new HashMap<>();
                map.put("realName", loginUser.getRealName());
                map.put("username", loginUser.getUsername());
                map.put("id", loginUser.getId()+"");
                map.put("password", loginUser.getPassword());
                map.put("deptName", loginUser.getDeptName());
                map.put("pic", loginUser.getPic());

                // 群发消息提醒
                XBWebSocket.sendMessageNotUser(loginUser.getId(), loginUser.getRealName() + "刚刚上线啦！赶快去撩TA");
                return new Result(true, "登录成功", map);
            } else msg = "";
        } else msg = "用户名不存在";
//        } else msg = "验证码有误，请重新输入";
        return new Result(false, msg, null);
    }


    /**
     * 用户列表 列表/查询
     *
     * @param page   页码
     * @param search 用户名搜索
     * @return 用户列表
     */
    @RequestMapping("/search")
    public Result selectPage(Integer page, String search) {
        String username = (String) session.getAttribute("loginUser");
        User loginUser = service.findByUsername(username);
        Page<User> userPage = service.findUser(loginUser, search, page);
        return new Result(true, "查询成功", userPage);
    }

    /**
     * 用户列表 关注/取关
     *
     * @param id    操作对象ID
     * @param state 操作对象状态
     * @return 响应结果集
     */
    @RequestMapping("/updateFocus")
    public Result updateFocus(Long id, Boolean state) {
        String username = (String) session.getAttribute("loginUser");
        User loginUser = service.findByUsername(username);
        String msg = service.updateMyFocus(loginUser.getId(), id, state);
        // 通知被关注方
        XBWebSocket.sendMessage(id, loginUser.getRealName() + "刚刚关注了您！");
        return new Result(true, "操作成功", msg);
    }

    /**
     * 查看登录用户信息
     *
     * @return 响应结果集 用户信息
     */
    @RequestMapping("/loginUserInfo")
    public Result loginUserInfo() {
        String username = (String) session.getAttribute("loginUser");
        User loginUser = service.findByUsername(username);
        return new Result(true, "查询成功", loginUser);
    }

    /**
     * 根据用户ID查询是否私密
     *
     * @return 响应结果集 是否私密
     */
    @RequestMapping("/detail/{userId}")
    public Result detail(@PathVariable Long userId) {
        return new Result("0".equals(service.findUserIsSecret(userId)) ? true : false, "查询成功");
    }

    /**
     * 根据ID查询用户信息
     *
     * @return 响应结果集 用户信息 粉丝数 收藏数
     */
    @RequestMapping("/findUser/{userId}")
    public Result findById(@PathVariable Long userId) {
        // 即时粉丝数
        User user = service.findById(userId);
        user.setFans(service.findFocus(userId));
        user.setLook(user.getLook() + 1);
        service.updateLook(user);
        // 被看数+1
        return new Result(true, "查询成功", user);
    }


//    @RequestMapping("/updateUserInfo")
//    public Result updateUserInfo(@RequestBody User user) {
//        updateUserInfo(user);
//        return new Result(true, "保存成功");
//    }


    @RequestMapping("/findMyFocus/{page}")
    public Result findMyFocus(@PathVariable Integer page) {
        String username = (String) session.getAttribute("loginUser");
        User loginUser = service.findByUsername(username);
        Page<User> pageData=service.findMyFocus(loginUser.getId(),page);
        return new Result(true, "查询成功",new PageResult<>(pageData.getTotalPages(),pageData.getContent()));
    }

    @PostMapping("/uploadPic")
    public Result uploadPic(MultipartFile pic) throws IOException {
        String username = (String) session.getAttribute("loginUser");
        User loginUser = service.findByUsername(username);

        // 文件的真实名称 abc.png
        String filename = pic.getOriginalFilename();
        // 得到文件后缀名
        String suffix = filename.substring(filename.lastIndexOf("."));
        // 随机文件名 xxx.png
        filename = UUID.randomUUID().toString() + suffix;
        // E:/upload/（随机名）xxx.png
        String dirPath = "E:/java42/code/Re_xbhy/upload/" + filename;
        // 将文件写入磁盘
        pic.transferTo(new File(dirPath));
        // 图片的网络地址（客户端访问地址）
        String url = "http://localhost:8080/upload/" + filename;
        // 修改数据库的头像地址
        service.updatePicUrl(loginUser.getId(), url);
        System.out.println(url);
        return new Result(true, "上传成功", url);
    }

    @RequestMapping("/findByDeptId/{deptId}")
    public Result findByDeptId(@PathVariable Long deptId){
        return new Result(true, "查询成功", service.findByDeptId(deptId));
    }

    /**
     * 用户注销
     *
     * @return
     */
    @PostMapping("/logout")
    public Result logout() {
        String username = (String) session.getAttribute("loginUser");
        User loginUser = service.findByUsername(username);
        // 删除redis中的信息
//        redisTemplate.delete("loginUser:" + session.getAttribute("userId"));

        // 清空session
        XBWebSocket.sendMessageNotUser(loginUser.getId(), loginUser.getRealName() + "刚刚下线了！");
        session.invalidate();
        return new Result(true, "注销成功");
    }
}
